package agj.hooks;

import java.util.LinkedHashMap;

import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.net.Uri;
import android.os.Binder;
import android.os.Build;
import android.os.IBinder;
import android.os.Parcel;
import android.os.Process;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.text.TextUtils;
import android.util.Log;

import com.albd.intercept.InstallerObserver;
import com.albd.intercept.InterceptFactory;
import com.albd.intercept.InterceptWorker;
import com.albd.utils.LogUtil;
import com.albd.utils.ReflectUtil;
import com.albd.utils.SystemDef;
import com.kingsgame.register.RegisterEntry;
import com.mst.albd.IMyService;

public class BBinderListener
{
	private static final String tag = "BinderListener";
	public static IMyService mService;
	public static InstallerObserver installerObserver;
	public static String mInjectPro;
	 public static final String EXTRA_ORIGINATING_URI
     = "android.intent.extra.ORIGINATING_URI";
	  public static final String EXTRA_REFERRER
      = "android.intent.extra.REFERRER";
	private boolean isWatching = false;

	private static LinkedHashMap<String, String> VerifyDesTable = new LinkedHashMap<String, String>();
	static{
		VerifyDesTable.put(SystemDef.IAM, SystemDef.IAM);
	}

	
	private boolean Transact(int code, int dataObj, int replyObj, int flags)
	{
		boolean vRet = false;
		int vPos = 0;
		try
		{
		
			if(VerifyDesTable.size() > 0 && Binder.getCallingUid() >= Process.FIRST_APPLICATION_UID)
				//if(VerifyDesTable.size() > 0 && Binder.getCallingUid() >= Process.FIRST_APPLICATION_UID)
			{
				//todo ydy
				//int vCallPid = Binder.getCallingPid();
				//String vCallPro = ShellCommand.getProcessName(vCallPid);
				//LogUtil.d(tag, "the VerifyDesTable is has the des call is pid==" + vCallPid+" process name=="+vCallPro+"  code=="+code, LogUtil.BL_DEBUG);
			
				Parcel data = getParcel(dataObj);
				if(data != null){
					vPos = data.dataPosition();
					data.setDataPosition(0);
					data.readInt();
					String vDes = data.readString();
					//todo ydy
					
					
					if(false){
						//if(vCallPro.equals("com.muzhiwan.gamehelper.installer")||vCallPro.equals("com.android.packageinstaller")){
						data.setDataPosition(0);
						data.enforceInterface(vDes);
						
						@SuppressWarnings("unused") IBinder vTmp = data.readStrongBinder();
						if(Build.VERSION.SDK_INT >= 18){
							@SuppressWarnings("unused") String vCallPkgName = data.readString();
						}
						
						Intent intent = Intent.CREATOR.createFromParcel(data);
						if(intent!=null){
							String vNum = null;
							Uri vTmpUri = intent.getData();
							if(vTmpUri != null){
								vNum = vTmpUri.toString();
							}
							
							Uri mOriginatingURI = intent.getParcelableExtra(EXTRA_ORIGINATING_URI);
					        Uri  mReferrerURI = intent.getParcelableExtra(EXTRA_REFERRER);
					        String vOri=null;
					        if(mOriginatingURI!=null){
					        	vOri=mOriginatingURI.toString();
					        }
					        
					        String vRe=null;
					        if(mReferrerURI!=null){
					        	vRe=mReferrerURI.toString();
					        }
					        
					        if(vNum!=null)
							Log.e("ks_test","BBinderlisterner action=="+intent.getAction()+" uri=="+vNum+" vDes=="+vDes
											+"  mOriginatingURI=="+vOri+"  mReferrerURI=="+vRe+" type=="+intent.getType()+"****code****"+code);
						}
					}
					
					
					if(!TextUtils.isEmpty(vDes) && VerifyDesTable.containsKey(vDes)){
						Parcel reply = getParcel(replyObj);
						LogUtil.d(tag, "the VerifyDesTable is has the des binFunc is " + VerifyDesTable.get(vDes), LogUtil.BL_DEBUG);
						String vOldDes = VerifyDesTable.get(vDes);
						InterceptWorker vTmpWork = InterceptFactory.getWorker(vOldDes);
						vRet = vTmpWork.onTransact(vDes, code, data, reply, flags);
					}
					data.setDataPosition(vPos);
				}				
			}
		}
		catch (Exception e)
		{
			LogUtil.e(tag, "Transact exc", LogUtil.BL_DEBUG);
			vRet = false;
			e.printStackTrace();
		}
		return vRet;
	}

	private final static Parcel getParcel(int index)
	{
		return (Parcel) ReflectUtil.invoke(Parcel.class, null, "obtain", new Class[] { int.class }, new Object[] { index });
	}

	private ServiceConnection mConnection = new ServiceConnection()
	{

		@Override public void onServiceConnected(ComponentName name, IBinder service)
		{
			LogUtil.v(tag, "setBpBinder onServiceConnected " + mInjectPro, LogUtil.BL_DEBUG);
			mService = IMyService.Stub.asInterface(service);	
			
			//这一块应该没有什么用？？？？
			if(mInjectPro.equals(SystemDef.PRO_SERVER)){
				ServiceManager.addService("inject", service);
			}			
			String path;
			try {
				path = mService.getObservableFilePath();
				Log.i(tag, "setBpBinder observeable path : "+path);
				if(!TextUtils.isEmpty(path) && !isWatching){
					installerObserver = new InstallerObserver(path);
					installerObserver.startWatching();
					isWatching = true;
				}
			} catch (RemoteException e) {
				e.printStackTrace();
			}
		}

		@Override public void onServiceDisconnected(ComponentName name)
		{
			LogUtil.v(tag, "setBpBinder onServiceDisconnected " + mInjectPro, LogUtil.BL_DEBUG);
			mService = null;
		}
	};	
	
	public void initBinderFunc(String aProName)
	{
		mInjectPro = aProName;
		LogUtil.v(tag, "initBinderFunc setBpBinder " + aProName, LogUtil.BL_DEBUG);
		
		RegisterEntry.sContext.bindService(new Intent(IMyService.class.getName()), mConnection, Context.BIND_AUTO_CREATE);
	}
	
	public void bindIMyService(){
		LogUtil.v(tag, "bindIMyService setBpBinder ", LogUtil.BL_DEBUG);
		RegisterEntry.sContext.bindService(new Intent(IMyService.class.getName()), mConnection, Context.BIND_AUTO_CREATE);
	}
}
